package com.ls.thread;

import java.lang.reflect.Field;
import java.util.Queue;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolTest {
    public static void main(String[] args) {
        // 创建线程池
        AtomicInteger c = new AtomicInteger(1);
        ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2, // 定义两个核心线程
                3, // 总共的线程数，也就是说救急线程有1个
                0, // 救急线程存活时间，0的话就是说执行完就释放
                TimeUnit.MILLISECONDS,
                queue,
                r -> new Thread(r,"myThread"+c.getAndIncrement()), // 线程创建工厂
                new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
        );
        showState(queue,threadPool); // 没有提交线程
        threadPool.submit(new MyTask("1",1000L*30));
        showState(queue,threadPool); // 提交一个线程，直接从线程池拿一个线程执行 核心线程还剩下一个
        threadPool.submit(new MyTask("2",1000L*30));
        showState(queue,threadPool); // 第二个线程，再直接从线程池拿一个线程执行 核心线程还剩下0个
        threadPool.submit(new MyTask("3"));
        showState(queue,threadPool); // 第三个线程，放到队列中去 队列还剩一个位置
        threadPool.submit(new MyTask("4"));
        showState(queue,threadPool); // 第四个线程，放到队列中去  队列没有位置了
        threadPool.submit(new MyTask("5",1000L*30));
        showState(queue,threadPool); // 第五个线程，队列满了,使用救急线程
        threadPool.submit(new MyTask("6",1000L*30));
        showState(queue,threadPool); // 第六个线程，队列满了,1个救急线程也已经用了，就要使用四种拒绝策略去拒绝了

    }

    static class MyTask implements Runnable{

        private final String name;
        private final long duration;

        public MyTask(String name, Long duration) {
            this.name = name;
            this.duration = duration;
        }

        public MyTask(String name) {
            this(name,0L);
        }

        @Override
        public void run() {
            try {
                System.out.println("running"+this.name);
                Thread.sleep(duration);
                System.out.println(this.name + "ok");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            return "MyTask{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }


    public static void showState(ArrayBlockingQueue<Runnable> queue,ThreadPoolExecutor threadPool){
        int poolSize = threadPool.getPoolSize();
        System.out.println("queue:"+ queue.size()+"--->"+"threadPool:"+poolSize);
    }
}
